package com.autoscript.service;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.autoscript.ISystemConstant;
import com.autoscript.endpoint.WebSocket;
import com.autoscript.ext.xmldata.dbmodel.DBModel;
import com.autoscript.ext.xmldata.dbmodel.IDBModel;
import com.autoscript.ext.xmldata.dbmodel.ITableModel;
import com.autoscript.ext.xmldata.pdm.parse.PdmParse;
import com.autoscript.ext.xmldata.sql.parse.SqlParse;
import com.autoscript.ui.core.processor.parse.file.FileParse;
import com.autoscript.ui.core.processor.parse.file.IFileParse;
import com.autoscript.ui.helper.FileCtrlUtils;
import com.autoscript.ui.helper.TemplateHelper;
import com.autoscript.ui.helper.TemplateHelperException;
import com.autoscript.ui.helper.XMLHelper;
import com.autoscript.ui.model.xml.IXmlNode;
import com.autoscript.utils.SessionMap;
import com.autoscript.utils.WebSocketList;
import com.autoscript.utils.ZipUtils;
import com.autoscript.vo.RunlogVo;
import com.dfhc.util.DateUtil;
import com.dfhc.util.FileOperateHelper;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.dfhc.securitydb.service.SecurityDBClientService;
import com.dfhc.util.StringHelper;
import com.autoscript.vo.ProjectVo;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 工程表服务
 * @author lsb
 * @version 1.0.0
 * @date 2021-02-02
 */
@Service
public class ProjectService {
	private static Logger logger=LoggerFactory.getLogger(ProjectService.class);
	@Autowired
	private PublicService publicService;
	@Autowired
	private RunlogService runlogService;
	@Autowired
	private TemplateService templateService;
	@Autowired
	private WebSocketList webSocketList;
	@Autowired
	private SessionMap sessionMap;
	@Autowired
	private ProjectParameterService projectParameterService;
	@Autowired
	private FileDownloadService fileDownloadService;
	/**
	 * 表名
	 */
	private String TABLE_NAME="AS_PROJECT";

	/**
	 * 统计记录数
	 * @param searchMap
	 * @return
	 */
	public long count(Map<String, Object> searchMap) {
		return SecurityDBClientService.getInstance().count(getDBSesion(), TABLE_NAME, searchMap);
	}

	/**
	 *  插入
	 * @param projectVo
	 * @throws Exception 
	 */
	public void insert(ProjectVo projectVo) throws Exception {
		Map<String, Object> data;
		data = new HashMap<String,Object>();
		//获取序列id
		if(StringHelper.isEmpty(projectVo.getId())){
			data.put("ID",publicService.getIds(TABLE_NAME, 1)[0]);
		}
		if(!StringHelper.isEmpty(projectVo.getId())){
			data.put("ID",projectVo.getId());
		}
		if(!StringHelper.isEmpty(projectVo.getProjectName())){
			data.put("PROJECT_NAME",projectVo.getProjectName());
		}
		if(!StringHelper.isEmpty(projectVo.getRemark())){
			data.put("REMARK",projectVo.getRemark());
		}
		if(!StringHelper.isEmpty(projectVo.getCreateDate())){
			data.put("CREATE_DATE",projectVo.getCreateDate());
		}
		if(!StringHelper.isEmpty(projectVo.getCreateUserId())){
			data.put("CREATE_USER_ID",projectVo.getCreateUserId());
		}
		if(!StringHelper.isEmpty(projectVo.getEncode())){
			data.put("ENCODE",projectVo.getEncode());
		}
		if(!StringHelper.isEmpty(projectVo.getIsDatasource())){
			data.put("IS_DATASOURCE",projectVo.getIsDatasource());
		}
		if(!StringHelper.isEmpty(projectVo.getCustomRunUrl())){
			data.put("CUSTOM_RUN_URL",projectVo.getCustomRunUrl());
        }
		//检查同一个用户下的工程名称是否存在
		Map countMap = new HashMap();
		countMap.put("CREATE_USER_ID",projectVo.getCreateUserId());
		countMap.put("PROJECT_NAME",projectVo.getProjectName());
		if(count(countMap)>0){
			logger.error("项目名称:"+projectVo.getProjectName()+"已经存在！数据为:"+data);
			throw new Exception("项目名称:"+projectVo.getProjectName()+"已经存在！");
		}
		int rowNum = SecurityDBClientService.getInstance().insert(getDBSesion(), TABLE_NAME, data);
		if(rowNum!=1) {
			logger.error("插入工程表失败！数据为:"+data+",rowNum:"+rowNum);
			throw new Exception("插入工程表失败！");
		}
	}
	
	/**
	 * 获取db会话
	 * @return
	 */
	private String getDBSesion() {
		return DBSessionService.getSingleInstance().getSession();
	}
	/**
	 * 更新工程表
	 * @param projectVo
	 * @return
	 * @throws Exception
	 */
	public int update(ProjectVo projectVo) throws Exception{
		Map<String, Object> searchMap;
		Map<String, Object> data;

		if(StringHelper.isEmpty(projectVo.getId()))
			throw new Exception("工程表id为空!");
		searchMap = new HashMap<String,Object>();
		
		searchMap.put("ID",projectVo.getId());
		data = new HashMap<String,Object>();
		if(!StringHelper.isEmpty(projectVo.getId())){
			data.put("ID",projectVo.getId());
		}
		if(!StringHelper.isEmpty(projectVo.getProjectName())){
			data.put("PROJECT_NAME",projectVo.getProjectName());
		}
		if(!StringHelper.isEmpty(projectVo.getRemark())){
			data.put("REMARK",projectVo.getRemark());
		}
		if(!StringHelper.isEmpty(projectVo.getCreateDate())){
			data.put("CREATE_DATE",projectVo.getCreateDate());
		}
		if(!StringHelper.isEmpty(projectVo.getCreateUserId())){
			data.put("CREATE_USER_ID",projectVo.getCreateUserId());
		}
		if(!StringHelper.isEmpty(projectVo.getEncode())){
			data.put("ENCODE",projectVo.getEncode());
		}
		if(!StringHelper.isEmpty(projectVo.getIsDatasource())){
			data.put("IS_DATASOURCE",projectVo.getIsDatasource());
		}
		data.put("CUSTOM_RUN_URL",projectVo.getCustomRunUrl());

		Map dbMap = getById(projectVo.getId());
		if(dbMap ==null){
			logger.error("工程id:"+projectVo.getId()+"找不到数据!");
			throw new Exception("工程id:"+projectVo.getId()+"找不到数据!");
		}
		//如果项目名称变化，则检查是否存在
		if(!dbMap.get("PROJECT_NAME").equals(projectVo.getProjectName())){
			Map countMap = new HashMap();
			countMap.put("CREATE_USER_ID",projectVo.getCreateUserId());
			countMap.put("PROJECT_NAME",projectVo.getProjectName());
			if(count(countMap)>0){
				logger.error("项目名称:"+projectVo.getProjectName()+"已经存在！数据为:"+data);
				throw new Exception("项目名称:"+projectVo.getProjectName()+"已经存在！");
			}
		}
		int rowNum = SecurityDBClientService.getInstance().update(getDBSesion(), TABLE_NAME, searchMap, data);
		if(rowNum<1) {
			logger.error("更新工程表失败!数据为:searchMap:"+searchMap+",data:"+data+",rowNum:"+rowNum);
			throw new Exception("更新工程表失败!");
		}
		return rowNum;
	}
	/**
	 * 删除工程表
	 * @param projectVo
	 * @return
	 * @throws Exception
	 */
	public int delete(ProjectVo projectVo) throws Exception{
		Map<String,Object> searchMap = new HashMap<String,Object>();
		if(!StringHelper.isEmpty(projectVo.getId())){
			searchMap.put("ID",projectVo.getId());
		}
		if(!StringHelper.isEmpty(projectVo.getProjectName())){
			searchMap.put("PROJECT_NAME",projectVo.getProjectName());
		}
		if(!StringHelper.isEmpty(projectVo.getRemark())){
			searchMap.put("REMARK",projectVo.getRemark());
		}
		if(!StringHelper.isEmpty(projectVo.getCreateDate())){
			searchMap.put("CREATE_DATE",projectVo.getCreateDate());
		}
		if(!StringHelper.isEmpty(projectVo.getCreateUserId())){
			searchMap.put("CREATE_USER_ID",projectVo.getCreateUserId());
		}
		if(!StringHelper.isEmpty(projectVo.getEncode())){
			searchMap.put("ENCODE",projectVo.getEncode());
		}
		if(!StringHelper.isEmpty(projectVo.getIsDatasource())){
			searchMap.put("IS_DATASOURCE",projectVo.getIsDatasource());
		}
		if(!StringHelper.isEmpty(projectVo.getCustomRunUrl())){
			searchMap.put("CUSTOM_RUN_URL",projectVo.getCustomRunUrl());
		}
		//删除工程参数
		projectParameterService.deleteByProjectId(projectVo.getId());
		//删除工程模版
		templateService.deleteByProjectId(projectVo.getId());
		int rowNum = SecurityDBClientService.getInstance().delete(getDBSesion(), TABLE_NAME, searchMap);
		if(rowNum<1) {
			logger.error("删除工程表失败,参数为:"+searchMap+",rowNum:"+rowNum);
			throw new Exception("删除工程表失败!");
		}
		return rowNum;		
	}

	/**
	 * 查询工程表
	 * @param searchMap 查询条件
	 * @param pageNo 页号
	 * @param pageSize 页大小
	 * @return
	 */
	public List<Map> listPage(Map<String, Object> searchMap, int pageNo, int pageSize) {

		return SecurityDBClientService.getInstance().search(getDBSesion(), 
				TABLE_NAME, searchMap, pageNo, pageSize);
	}
	/**
	 * 查询工程表
	 * @param searchMap 查询条件
	 * @return
	 */
	public List<Map> search(Map<String, Object> searchMap) {
		return SecurityDBClientService.getInstance().search(getDBSesion(), 
				TABLE_NAME, searchMap);
	}
	/**
	 * 根据id查询工程表
	 * @param id id标识
	 * @return
	 */
	public Map getById(String id) throws Exception {
		if(StringHelper.isEmpty(id))
			throw new Exception("工程表id为空!");
		Map<String,Object> searchMap = new HashMap<String,Object>();
		
		searchMap.put("ID",id);
		List<Map> resultList =  SecurityDBClientService.getInstance().search(getDBSesion(), 
				TABLE_NAME, searchMap);
 		if(resultList==null||resultList.size()==0){
 		  return null;
 		}else{
 		  return resultList.get(0);
 		}
	}

	/**
	 * 解析pdm，返回表列表
	 * @param request
	 * @throws IOException
	 */
	public List<Map<String, String>> parsePdm(HttpServletRequest request, byte bytes[]) throws Exception {
		List<Map<String, String>> tableList;
		PdmParse pdmParse = new PdmParse();
		IDBModel pdmModel = pdmParse.parse(bytes);
		List<ITableModel> tableModels = pdmModel.getTableModels();
		tableList = new ArrayList<>();
		Map<String,Object> hSessionMap = sessionMap.get(request.getHeader(ISystemConstant.SESSION_ID));
		if(hSessionMap==null){
			throw new Exception("请重新登录!");
		}
		//缓存session
		hSessionMap.put(ISystemConstant.PDM_MODEL, pdmModel);

		for(ITableModel tableModel:tableModels){
			Map<String,String> tableMap = new HashMap<>();
			tableMap.put(ISystemConstant.KEY,tableModel.getCode());
			tableMap.put(ISystemConstant.LABEL,tableModel.getName());
			tableList.add(tableMap);
		}
		return  tableList;
	}

	/**
	 * 产生代码
     * @param pdmModel
     * @param tableCodes 选择的表
     * @param logCode 日志编号
     * @param projectId 项目id
     * @param projectParameter
     * @return
     */
	@Async
	public String generateCode(IDBModel pdmModel, String[] tableCodes, String logCode, String projectId, Map<String, String> projectParameter,String loginSession) {
		Long startTime,endTime;
		String packFile ="";
		String runLogId ="";
		WebSocket ws=null;
		//等待网页连接
		while(ws==null) {
			ws = webSocketList.get(logCode);
			if(ws==null){
				try {
					logger.debug("等待客户端连接.");
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
					return "";
				}
			}
		}
		Map<String,Object> processMap  = new HashMap<>();
		processMap.put(ISystemConstant.AJAX_STATUS,ISystemConstant.AJAX_RESULT_SUCCESS);
		try {
			startTime = System.currentTimeMillis();
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"开始产生代码");
				processMap.put(ISystemConstant.PROGRESS,0);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
			logger.debug("开始产生代码...");
			//查询项目产生源码字符集
			String encode;

			Map projectMap = this.getById(projectId);
			if (projectMap == null)
				throw new Exception("项目id:" + projectId + "不存在!");
			encode = (String) projectMap.get("ENCODE");
			//产生源xml
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"产生源xml");
				processMap.put(ISystemConstant.PROGRESS,10);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
			String sourceXml = "";
			if (tableCodes != null && tableCodes.length > 0){
				sourceXml = makeSourceXml(pdmModel, tableCodes);
		    }
			runLogId = insertRunLog(loginSession, logCode, projectId, sourceXml);
			//从缓存克隆FreeMarker 扩展函数
			Map<String, Object> templateMap = null;
			logger.debug("构造扩展函数Map");
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"构造扩展函数Map");
				processMap.put(ISystemConstant.PROGRESS,20);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}

			templateMap = makeExtFunctionMap();
			//合并工程公共参数
			templateMap.putAll(projectParameter);
			//构造工作目录
			logger.debug("构造工作目录");
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"构造工作目录");
				processMap.put(ISystemConstant.PROGRESS,30);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
			String workDir = getWorkDir(runLogId);
			//把模型的xml和模板数据以文件格式存到工作目录/模板目录.
			logger.debug("把模型的xml和模板数据以文件格式存到工作目录/模板目录");
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"把模型的xml和模板数据以文件格式存到工作目录");
				processMap.put(ISystemConstant.PROGRESS,40);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
			List<String> templateFiles = saveTemplateToFile(workDir, projectId, encode);
			//产生中间文件...
			logger.debug("产生中间文件");
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"产生中间文件");
				processMap.put(ISystemConstant.PROGRESS,50);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
			List<String> interMediateFiles = buildInterMediateFile(workDir, templateFiles, encode, sourceXml, templateMap);
			//根据中间文件，产生结果文件
			logger.debug("根据中间文件，产生结果文件");
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"根据中间文件，产生结果文件");
				processMap.put(ISystemConstant.PROGRESS,60);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
			makeResultFile(interMediateFiles, workDir);
			//打包文件
			logger.debug("打包文件");
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"打包文件");
				processMap.put(ISystemConstant.PROGRESS,70);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
			packFile = makePackFile(workDir, runLogId);
			//更新运行日志表
			logger.debug("更新运行日志表");
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"更新运行日志表");
				processMap.put(ISystemConstant.PROGRESS,90);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
			endTime = System.currentTimeMillis();
			String msg = "结束产生代码，耗时:" + (endTime - startTime) + "毫秒!";
			updateRunLog(runLogId, msg, packFile, ISystemConstant.DICTIONARY_RM_YES_NOT_1, DateUtil.getNowDate("yyyy-MM-dd HH:mm:ss"),projectParameter);
			logger.debug(msg);
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,msg);
				processMap.put(ISystemConstant.PROGRESS,100);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
		}catch(Exception e){
        	logger.error("生成代码出错",e);
			if(ws!=null){
				processMap.put(ISystemConstant.AJAX_MESSAGE,"生成代码出错:"+e.getMessage());
				processMap.put(ISystemConstant.AJAX_STATUS,ISystemConstant.AJAX_RESULT_FAIL);
				ws.sendOneMessage(JSON.toJSONString(processMap));
			}
        	try {
				updateRunLog(runLogId, e.getMessage(), packFile, ISystemConstant.DICTIONARY_RM_YES_NOT_0, DateUtil.getNowDate("yyyy-MM-dd HH:mm:ss"),projectParameter);
			}catch(Exception e1){
        		logger.error("更新运行日志失败!",e1);
			}
		}

        return runLogId;
    }

	/**
	 * 构造源xml
	 * @param pdmModel
	 * @param tableCodes 选择表数组
	 * @return  源xml
	 */
	private String makeSourceXml(IDBModel pdmModel,String[] tableCodes) throws Exception{
		//从会话里获取pdm模型
			//IDBModel pdmModel =	(IDBModel)session.getAttribute(ISystemConstant.PDM_MODEL);
			if(pdmModel!=null) {
				IDBModel selectTabPdmModel = new DBModel();
				selectTabPdmModel.setReferenceModels(pdmModel.getReferenceModels());
				selectTabPdmModel.setDomainModels(pdmModel.getDomainModels());
				//循环增加选择表模型
				for (String tableCode : tableCodes) {
					for (ITableModel tableModel : pdmModel.getTableModels()) {
						if (tableModel.getCode().equals(tableCode)) {
							selectTabPdmModel.getTableModels().add(tableModel);
							break;
						}
					}
				}
				return selectTabPdmModel.toXml();
			}else{
				return "";
			}
		//}else
		//	throw new Exception("请登录系统!");
	}
	/**
	 * 插入运行日志
	 * @param loginSession
	 * @param logCode 日志编号
	 * @param projectId 工程id
	 * @param sourceXml 源xml
	 */
	private String insertRunLog(String loginSession,String logCode,String projectId,String sourceXml) throws Exception {
		RunlogVo runlogVo = new RunlogVo();

		runlogVo.setLogCode(logCode);
		runlogVo.setProjectId(projectId);
		runlogVo.setSourceData(sourceXml);
		if(loginSession!=null){
			Map currentUser = (Map)sessionMap.get(loginSession);
			if(currentUser!=null) {
				runlogVo.setRunUserId((String) currentUser.get(ISystemConstant.CURRENT_USER_ID));
			}else {
				throw new Exception("请登录系统!");
			}
		}else {
			throw new Exception("请登录系统!");
		}
		runlogVo.setStartTime(DateUtil.getNowDate("yyyy-MM-dd HH:mm:ss"));
		Map<String, Object> m = runlogService.insert(runlogVo);
		return (String)m.get("ID");
	}

	/**
	 * 构造FreeMarker扩展函数Map
	 */
	private Map<String, Object> makeExtFunctionMap() {
		Map<String, Object> templateMap;
		//从缓存里获取扩展函数Map
		templateMap = (Map<String, Object>)ParameterCacheService.getSingleInstance().get(ISystemConstant.ALL_FREEMARKER_EXT_FUNCTION);
		return templateMap;
	}

	/**
	 * 获取工作目录
	 * @param  runLogId 项目id
	 * @return
	 */
	private String getWorkDir(String runLogId){
	    //从缓存里获取根目录+工作相对目录
		String workRootDir = ParameterCacheService.getSingleInstance().get(ISystemConstant.ROOT_DIR)+ File.separator+ISystemConstant.RELA_WORK_DIR;
		//完整目录=根目录+工作相对目录+项目id
		return workRootDir+File.separator+runLogId+File.separator;
	}

	/**
	 * 保存模板为文件
	 * @param workDir 工作目录
	 * @param projectId 项目id
	 * @param encode 字符集
	 * @return 输出文件列表
	 */
	private List<String> saveTemplateToFile(String workDir, String projectId,String encode) throws Exception{
		List<String> retFiles = new ArrayList<>();
		String templatePath = workDir + ISystemConstant.TEMPLDATE_PATH + File.separator;
		// 自动创建目录
		if (!FileOperateHelper.isExists(templatePath)) {
			FileOperateHelper.newFolder(templatePath);
		}
		//查询工程中启用的模板
		Map<String, Object> searchMap = new HashMap<>();

		searchMap.put("PROJECT_ID",projectId);
		searchMap.put("IS_ENABLE",ISystemConstant.DICTIONARY_RM_YES_NOT_1);
		List<Map> templateMaps = templateService.search(searchMap);
		if(templateMaps==null||templateMaps.size()==0)
			throw new Exception("项目没有模板或者启用的模板!");
		// 循环保存模板文件
		String templateFile;
		for (Map templateMap :templateMaps) {
				templateFile = templatePath + (String)templateMap.get("TEMPLATE_NAME") + ISystemConstant.TEMPLATE_SUFFIX;
				FileOperateHelper.writeStringToFile(new File(templateFile), (String)templateMap.get("TEMPLATE_CONTENT"),
						encode);
				retFiles.add(templateFile);
		}
		return retFiles;
	}

	/**
	 * 生成中间文件
	 * @param workDir 工作目录
	 * @param templateFiles 模板文件列表
	 * @param encode 输出文件字符集
	 * @param sourceXml xml源数据
	 * @param  templateMap Freemarker扩展函数Map
	 * @return 返回中间文件列表
	 */
	private List<String> buildInterMediateFile(String workDir,List<String> templateFiles,String encode,String sourceXml,Map<String, Object> templateMap) throws Exception {
		List<String> retFiles = new ArrayList<String>();
		// 将xml转换为模型
		IXmlNode rootNode = null;
		try {
			if(!StringHelper.isEmpty(sourceXml)) {
				rootNode = XMLHelper.xml2Model(sourceXml);
			}
		} catch (DocumentException e1) {
			throw new TemplateHelperException(e1);
		}
		String intermediatePath;
		intermediatePath = workDir + ISystemConstant.INTERMEDIATE_PATH + File.separator;
		if (!FileOperateHelper.isExists(intermediatePath)) {
			FileOperateHelper.newFolder(intermediatePath);
		}
		// 循环产生中间文件
		templateMap.put(ISystemConstant.ROOT_NODE, rootNode);
		for (String templateFile:templateFiles) {
			String intermediateFile;
			String templateFileName = FileOperateHelper.getFileName(templateFile);
			intermediateFile = intermediatePath + FileOperateHelper.getFilePrefix(templateFileName)  + ISystemConstant.INTERMEDIATE_SUFFIX;
            logger.info("中间文件:"+intermediateFile);
            if(!FileOperateHelper.isExists(intermediateFile)){
            	FileOperateHelper.newFile(intermediateFile,"");
			}
			TemplateHelper.createFileByPathInCharset(templateMap, templateFile, intermediateFile,encode);
			//addOutputMessage("生成中间文件：" + intermediateFile);
			retFiles.add(intermediateFile);

		}
		return retFiles;
	}

	/**
	 * 根据中间文件产生结果文件
	 * @param workDir 工作目录
	 * @param interMediateFiles 中间文件列表
	 */
	private void makeResultFile(List<String> interMediateFiles,String workDir) throws Exception {
		IFileParse fileParse = new FileParse(null);
		String resultDir = workDir+ISystemConstant.RESULT_PATH;
		for(String interMediateFile:interMediateFiles){
			try {
				fileParse.parse(interMediateFile, resultDir);
			}catch(Exception e){
				logger.error("解析中间文件:"+interMediateFile+"出错!",e);
				throw e;
			}
		}
	}

	/**
	 * 结果文件打包
	 * @param workDir 工作目录
	 * @return 返回结果文件
	 */
	private String makePackFile(String workDir,String runLogId) throws Exception{
		String targetFileName;
		String resultDir = workDir+ISystemConstant.RESULT_PATH;
		FileCtrlUtils.createDir(resultDir);
		targetFileName = workDir+runLogId+".zip";
		ZipUtils.zip(resultDir,targetFileName);
		return targetFileName;
	}

	/**
	 * 更新运行日志
	 * @param runLogId 运行日志id
	 * @param msg
	 * @param packFile 压缩文件名
	 * @param successFailFlag 成功失败标志
	 * @param endTime 结束时间
	 * @param projectParameter
	 */
	private void updateRunLog(String runLogId, String msg, String packFile, String successFailFlag, String endTime, Map<String, String> projectParameter) throws Exception{
		RunlogVo runLogVo = new RunlogVo();

		runLogVo.setId(runLogId);
		((RunlogVo) runLogVo).setErrorMsg(msg);
		((RunlogVo) runLogVo).setResultFile(packFile);
		((RunlogVo) runLogVo).setSuccessFailFlag(successFailFlag);
		((RunlogVo) runLogVo).setEndTime(endTime);
		runLogVo.setProjectParameter(JSON.toJSONString(projectParameter));
		runlogService.update(runLogVo);
	}

	/**
	 * 导出工程
	 * @param projectVo
	 * @param response
	 */
    public void export(Map projectVo, HttpServletResponse response) throws Exception {
		if(projectVo==null)
			throw new Exception("项目vo为空!");
		//查询工程参数
		Map<String, Object> sessionProjectParamerMap;
		sessionProjectParamerMap = new HashMap<>();
		sessionProjectParamerMap.put("PROJECT_ID",projectVo.get("ID"));
		List<Map> projectParameterVos = projectParameterService.search(sessionProjectParamerMap);
		//查询工程模版列表
		//查询工程中启用的模板
		Map<String, Object> searchMap = new HashMap<>();

		searchMap.put("PROJECT_ID",projectVo.get("ID"));
		List<Map> templateMaps = templateService.search(searchMap);

		//转成三个json串，分别存到一个文件
		String tempRunLogId = StringHelper.getUUID();
		String workDir = getWorkDir(tempRunLogId);
		String resultDir = workDir+ISystemConstant.RESULT_PATH;
		FileCtrlUtils.createDir(resultDir);

		FileCtrlUtils.writeStringToFile(new File(resultDir+File.separator+ISystemConstant.PROJECT_FILE),JSON.toJSONString(projectVo),ISystemConstant.ENCODE_UTF_8);
		FileCtrlUtils.writeStringToFile(new File(resultDir+File.separator+ISystemConstant.PROJECT_PARAMETER_FILE),JSON.toJSONString(projectParameterVos),ISystemConstant.ENCODE_UTF_8);
		FileCtrlUtils.writeStringToFile(new File(resultDir+File.separator+ISystemConstant.TEMPLATE_FILE),JSON.toJSONString(templateMaps),ISystemConstant.ENCODE_UTF_8);

		//三个文件压缩成zip
		String targetFileName;

		targetFileName = workDir+tempRunLogId+".zip";
		ZipUtils.zip(resultDir,targetFileName);
		//下载
		fileDownloadService.download(targetFileName,response);
		//删除工作目录
		logger.info("delete dir"+workDir);
		FileCtrlUtils.deleteDirectory(new File(workDir));
    }
	/**
	 * 导入工程
	 */
	public void importProject(HttpServletRequest request, byte[] bytes) throws  Exception {
		//将字节流写到一个文件
		String tempRunLogId = StringHelper.getUUID();
		String workDir = getWorkDir(tempRunLogId);
		String resultDir = workDir+ISystemConstant.RESULT_PATH+File.separator;
		String zipFile = workDir+File.separator+"import.zip";
		FileCtrlUtils.createDir(resultDir);
		try {
			FileCtrlUtils.writeByteArrayToFile(new File(zipFile), bytes);
			//尝试解压
			ZipUtils.unZip(zipFile, resultDir);
			//检查文件数
			Collection files = FileCtrlUtils.listFiles(new File(resultDir), null, false);
			if (files != null && files.size() == 3) {
				//分别读取三个文件，将json反序列化为对象
				HashMap projectVo;
				List<HashMap> projectParameterVos;
				List<HashMap> templateVos;
				String jsonStr;

				jsonStr = FileCtrlUtils.readFileToString(new File(resultDir+File.separator+ISystemConstant.PROJECT_FILE),ISystemConstant.ENCODE_UTF_8);
				projectVo = JSON.parseObject(jsonStr,HashMap.class);
				if(projectVo!=null) {
					logger.info("project vo:"+JSON.toJSONString(projectVo));
				}else{
					logger.info("project vo is null");
				}
				jsonStr = FileCtrlUtils.readFileToString(new File(resultDir+File.separator+ISystemConstant.PROJECT_PARAMETER_FILE),ISystemConstant.ENCODE_UTF_8);
				projectParameterVos = JSON.parseArray(jsonStr,HashMap.class);
				if(projectParameterVos!=null){
					logger.info("projectParameterVos size:"+projectParameterVos.size());
				}else{
					logger.info("projectParameterVos is null");
				}
				jsonStr = FileCtrlUtils.readFileToString(new File(resultDir+File.separator+ISystemConstant.TEMPLATE_FILE),ISystemConstant.ENCODE_UTF_8);
				templateVos = JSON.parseArray(jsonStr,HashMap.class);
			    if(templateVos!=null){
			    	logger.info("templateVos size:"+templateVos.size());
				}else{
			    	logger.info("templateVos is null");
				}
				//检查相同的工程名称是否存在，存在更新，不存在插入
				Map<String,Object> searchMap;
				searchMap = new HashMap<>();
				searchMap.put("PROJECT_NAME",projectVo.get("PROJECT_NAME"));
				List<Map> projectVos = search(searchMap);
				if(CollectionUtils.isEmpty(projectVos)){
					projectVo.put("ID",publicService.getIds(TABLE_NAME, 1)[0]);
					int rowNum = SecurityDBClientService.getInstance().insert(getDBSesion(), TABLE_NAME, projectVo);
					if(rowNum!=1) {
						logger.error("插入工程表失败！数据为:"+projectVo+",rowNum:"+rowNum);
						throw new Exception("插入工程表失败！");
					}
				}else{
					projectVo.put("ID",projectVos.get(0).get("ID"));
					searchMap.clear();
					searchMap.put("ID",projectVos.get(0).get("ID"));
					int rowNum = SecurityDBClientService.getInstance().update(getDBSesion(), TABLE_NAME, searchMap, projectVo);
					if(rowNum<1) {
						logger.error("更新工程表失败!数据为:searchMap:"+searchMap+",data:"+projectVo+",rowNum:"+rowNum);
						throw new Exception("更新工程表失败!");
					}
				}
				if(!CollectionUtils.isEmpty(projectVos)) {
					//删除原来的工程参数表记录
					projectParameterService.deleteByProjectId((String)projectVo.get("ID"));
					//删除原来的的工程模版列表
					templateService.deleteByProjectId((String)projectVo.get("ID"));
				}
				//插入新的工程参数记录
				for(Map m:projectParameterVos){
					m.put("ID",publicService.getIds(ProjectParameterService.TABLE_NAME, 1)[0]);
					m.put("PROJECT_ID",projectVo.get("ID"));
				}
				projectParameterService.insertBatch(projectParameterVos);
				//插入新的工程模版列表
				for(Map m:templateVos){
					m.put("ID",publicService.getIds(TemplateService.TABLE_NAME, 1)[0]);
					m.put("PROJECT_ID",projectVo.get("ID"));
				}
				templateService.insertBatch(templateVos);
			}else{
				throw new Exception("文件个数不对!");
			}
		}finally {
			// 删除工作目录
			logger.info("delete dir:"+workDir);
			FileCtrlUtils.deleteDirectory(new File(workDir));
		}

	}

	/**
	 * 导入sql文件
	 * @param request
	 * @param bytes
	 * @param dbType
	 * @return
	 */
	public List<Map<String, String>> parseSql(HttpServletRequest request, byte[] bytes, String dbType) throws Exception {
		List<Map<String, String>> tableList;
		SqlParse sqlParse = new SqlParse();
		String sql;
		sql = new String(bytes,ISystemConstant.ENCODE_UTF_8);
		IDBModel pdmModel = sqlParse.parseCreateSql(sql,dbType);
		List<ITableModel> tableModels = pdmModel.getTableModels();
		tableList = new ArrayList<>();
		Map<String,Object> hSessionMap = sessionMap.get(request.getHeader(ISystemConstant.SESSION_ID));
		if(hSessionMap==null){
			throw new Exception("请重新登录!");
		}
		//缓存session

		hSessionMap.put(ISystemConstant.PDM_MODEL, pdmModel);

		for(ITableModel tableModel:tableModels){
			Map<String,String> tableMap = new HashMap<>();
			tableMap.put(ISystemConstant.KEY,tableModel.getCode());
			tableMap.put(ISystemConstant.LABEL,tableModel.getName());
			tableList.add(tableMap);
		}
		return  tableList;
	}
}
